use crate::models::customer_favorites::{self, CreateParams};
use axum::{
    Json, Router,
    extract::State,
    routing::{get, post},
};
use loco_rs::prelude::*;

pub fn routes() -> Router<AppContext> {
    Router::new()
        .route("/customer-favorites", post(create))
        .route("/customer-favorites/:id", get(get_by_id))
        .route("/customer-favorites/:id/delete", post(delete))
        .route(
            "/customer-favorites/by-customer/:customer_id",
            get(get_by_customer),
        )
        .route(
            "/customer-favorites/by-customer/:customer_id/product/:product_id",
            get(get_by_customer_and_product),
        )
}

async fn create(
    State(state): State<AppContext>,
    Json(params): Json<CreateParams>,
) -> Result<Response> {
    let customer_favorite = customer_favorites::Model::create(&state.db, &params).await?;
    format::json(customer_favorite)
}

async fn get_by_id(
    State(state): State<AppContext>,
    axum::extract::Path(id): axum::extract::Path<String>,
) -> Result<Response> {
    let customer_favorite = customer_favorites::Model::find_by_id(&state.db, &id).await?;
    format::json(customer_favorite)
}

async fn delete(
    State(state): State<AppContext>,
    axum::extract::Path(id): axum::extract::Path<String>,
) -> Result<Response> {
    let customer_favorite = customer_favorites::Model::find_by_id(&state.db, &id).await?;
    customer_favorite.delete(&state.db).await?;
    format::json(())
}

async fn get_by_customer(
    State(state): State<AppContext>,
    axum::extract::Path(customer_id): axum::extract::Path<String>,
) -> Result<Response> {
    let customer_favorites =
        customer_favorites::Model::find_by_customer_id(&state.db, &customer_id).await?;
    format::json(customer_favorites)
}

async fn get_by_customer_and_product(
    State(state): State<AppContext>,
    axum::extract::Path((customer_id, product_id)): axum::extract::Path<(String, String)>,
) -> Result<Response> {
    let customer_favorite = customer_favorites::Model::find_by_customer_and_product(
        &state.db,
        &customer_id,
        &product_id,
    )
    .await?;
    format::json(customer_favorite)
}
